package com.mcp.converter.domain.rule.compatibility.function;

import com.mcp.converter.domain.checker.IncompatibilityDetail;
import com.mcp.converter.shared.response.sql.SQLElement;
import com.mcp.converter.domain.rule.compatibility.AbstractFunctionRule;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * PIVOT/UNPIVOT子句兼容性规则。
 * OceanBase不支持PIVOT/UNPIVOT语法。
 * @author zengxiong
 */
public class PivotUnpivotRule extends AbstractFunctionRule {

    private static final String RULE_ID = "FN010";
    private static final String RULE_NAME = "PIVOT/UNPIVOT子句兼容性";
    private static final String RULE_DESCRIPTION = "OceanBase不支持PIVOT和UNPIVOT子句。";

    public PivotUnpivotRule() {
        super(RULE_ID, RULE_NAME, RULE_DESCRIPTION);
        setIncompatibilityDetail(
                "OceanBase不支持Oracle中用于将行转换为列（PIVOT）和将列转换为行（UNPIVOT）的PIVOT和UNPIVOT子句。",
                "使用PIVOT或UNPIVOT语法的查询在OceanBase中将会失败。这些子句实现的数据转换逻辑需要使用其他SQL结构重新实现或在应用层面处理。",
                "重写使用PIVOT或UNPIVOT的查询。对于PIVOT，通常可以使用条件聚合（例如：SUM(CASE WHEN ... THEN ... END)）。对于UNPIVOT，通常可以使用一系列UNION ALL语句来规范化数据。对于复杂场景，也可以考虑在应用层面进行数据转换。",
                IncompatibilityDetail.Severity.HIGH
        );
    }

    @Override
    public boolean matches(Object target) {
        if (target instanceof SQLElement) {
            SQLElement element = (SQLElement) target;
            // 1. 直接判断元素名
            String elementName = element.getName();
            if (elementName != null) {
                String upperName = elementName.toUpperCase();
                if ("PIVOT".equals(upperName) || "UNPIVOT".equals(upperName)) {
                    return true;
                }
            }
            // 2. 针对FROM_CLAUSE、SUBQUERY、OTHER等类型，分析SQL片段内容
            if (element.getType() == com.mcp.converter.shared.enums.SQLElementType.FROM_CLAUSE
                    || element.getType() == com.mcp.converter.shared.enums.SQLElementType.SUBQUERY
                    || element.getType() == com.mcp.converter.shared.enums.SQLElementType.OTHER) {
                String value = element.getValue();
                if (value != null) {
                    String upperValue = value.toUpperCase();
                    // 仅匹配独立关键字，避免误报
                    if (upperValue.matches(".*\\bPIVOT\\b.*") || upperValue.matches(".*\\bUNPIVOT\\b.*")) {
                        return true;
                    }
                }
            }
            // 3. 可递归检查子元素
            if (element.hasChildren()) {
                for (SQLElement child : element.getChildren()) {
                    if (matches(child)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    
    @Override
    public Set<String> getIncompatibleFunctions() {
        return new HashSet<>(Arrays.asList("PIVOT", "UNPIVOT"));
    }
}
